package com.xinsoft.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xinsoft.common.exception.BDException;
import com.xinsoft.entity.dto.SysRoleDTO;
import com.xinsoft.entity.po.SysRole;
import com.xinsoft.entity.po.SysRoleMenu;
import com.xinsoft.entity.po.SysUserRole;
import com.xinsoft.entity.vo.SysRoleVo;
import com.xinsoft.mapper.SysRoleMapper;
import com.xinsoft.service.SysRoleMenuService;
import com.xinsoft.service.SysRoleService;
import com.xinsoft.service.SysUserRoleService;
import lombok.Synchronized;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
* @author xuhb
* @description 针对表【sys_role(角色表)】的数据库操作Service实现
* @createDate 2023-04-10 11:34:27
*/
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole>
    implements SysRoleService{

    @Resource
    private SysUserRoleService sysUserRoleService;

    @Resource
    private SysRoleMenuService sysRoleMenuService;


    /**
     * @Author hsm
     * @Description 增加权限
     * @Date 2023-04-10 10:34:27
     * @params sysRoleDTO
     * @return SysRole
     **/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public SysRole addSysRole(SysRoleDTO sysRoleDTO){

        //检查是否重名
        checkRoleName(sysRoleDTO);
        SysRole sysRole = new SysRole();
        BeanUtils.copyProperties(sysRoleDTO,sysRole);
        this.save(sysRole);
        if(CollectionUtil.isNotEmpty(sysRoleDTO.getMenuIds())){
            List<SysRoleMenu> roleMenuList = new ArrayList();
            for (Integer menuId : sysRoleDTO.getMenuIds()) {
                SysRoleMenu roleMenu = new SysRoleMenu();
                roleMenu.setRoleId(sysRole.getId());
                roleMenu.setMenuId(menuId);
                roleMenuList.add(roleMenu);
            }
            sysRoleMenuService.saveBatch(roleMenuList);
        }

        return sysRole;

    }

    @Override
    @Synchronized
    @Transactional(rollbackFor = Exception.class)
    public SysRole editSysRole(SysRoleDTO sysRoleDTO){

        //检查是否重名
        checkRoleName(sysRoleDTO);
        SysRole sysRole = new SysRole();
        BeanUtils.copyProperties(sysRoleDTO,sysRole);
        sysRole.setId(sysRoleDTO.getId());
        this.updateById(sysRole);
        sysRoleMenuService.removeByRoleId(sysRoleDTO.getId());
        if(CollectionUtil.isNotEmpty(sysRoleDTO.getMenuIds())){
            List<SysRoleMenu> roleMenuList = new ArrayList();
            for (Integer menuId : sysRoleDTO.getMenuIds()) {
                SysRoleMenu roleMenu = new SysRoleMenu();
                roleMenu.setRoleId(sysRole.getId());
                roleMenu.setMenuId(menuId);
                roleMenuList.add(roleMenu);
            }
            sysRoleMenuService.saveBatch(roleMenuList);
        }
        return sysRole;

    }

    @Override
    public SysRoleDTO getSysRole(Integer id) {
        SysRoleDTO result = new SysRoleDTO();
        SysRole role = this.getById(id);
        BeanUtils.copyProperties(role,result);
        QueryWrapper roleMenuQuery = new QueryWrapper();
        roleMenuQuery.select("menu_id");
        roleMenuQuery.eq("role_id",id);
        List<SysRoleMenu> sysRoleMenus = sysRoleMenuService.list(roleMenuQuery);
        if(CollectionUtil.isNotEmpty(sysRoleMenus)){
            List<Integer>  menuIds = sysRoleMenus.stream().map(SysRoleMenu::getMenuId).collect(Collectors.toList());
            result.setMenuIds(menuIds);
        }
        return result;
    }

    /**
     * @Author hsm
     * @Description 检查名称是否重复
     * @Date 2023-04-10 10:34:27
     * @params sysRoleDTO
     * @return SysRole
     **/
    private void checkRoleName(SysRoleDTO sysRoleDTO){
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("role_name",sysRoleDTO.getRoleName());
        queryWrapper.ne(sysRoleDTO.getId()!=null,"id",sysRoleDTO.getId());
        List roles = this.list(queryWrapper);
        if(roles.size()!=0){
            throw new BDException("角色名称系统中已存在，请勿重复！");
        }
    }

    @Override
    @Synchronized
    @Transactional(rollbackFor = Exception.class)
    public void del(List<Integer> ids) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.in("role_id",ids);
        queryWrapper.eq("do_delete",0);
        List list = sysUserRoleService.list(queryWrapper);
        if(list.size()>0){
            throw new BDException("操作失败，角色已经被使用无法使用！");
        }
        // 删除
        removeByIds(ids);

        QueryWrapper roleMenuQuery = new QueryWrapper();
        roleMenuQuery.in("menu_id",ids);
        sysRoleMenuService.remove(queryWrapper);

    }

    @Override
    public List<SysRole> getRoleListByUserId(Integer userId) {
        QueryWrapper userRoleQuery = new QueryWrapper();
        userRoleQuery.select("role_id");
        userRoleQuery.eq("user_id",userId);
        List<SysUserRole> userRoleDoList = sysUserRoleService.list(userRoleQuery);
        if(CollectionUtil.isEmpty(userRoleDoList)){
            return null;
        }
        List<Integer>  roleIds = userRoleDoList.stream().map(SysUserRole::getRoleId).collect(Collectors.toList());
        QueryWrapper roleQuery = new QueryWrapper();
        roleQuery.in(CollectionUtil.isNotEmpty(roleIds),"id",roleIds);
        roleQuery.eq("do_delete",0);
        List<SysRole> roleList = this.list(roleQuery);
        return roleList;
    }

    @Override
    public List<SysRoleVo> getRoleList() {
        return this.baseMapper.findList();
    }

}




